package proto

import (
	"encoding/xml"
)

// DTD 基于 XML 的客户端、服务端请求和响应数据结构
// https://datatracker.ietf.org/doc/html/draft-mavrogiannopoulos-openconnect-03#appendix-C.1

// 根元素 - 统一处理三种类型的响应
type DTD struct {
	XMLName              xml.Name      `xml:"config-auth"`
	Client               string        `xml:"client,attr"`                 // 固定值"vpn"
	Type                 string        `xml:"type,attr"`                   // auth-request|complete|otp
	AggregateAuthVersion int           `xml:"aggregate-auth-version,attr"` // 2
	Opaque               *Opaque       `xml:"opaque,omitempty"`
	Auth                 *Auth         `xml:"auth,omitempty"`
	SessionID            string        `xml:"session-id,omitempty"`
	SessionToken         string        `xml:"session-token,omitempty"`
	Capabilities         *Capabilities `xml:"capabilities,omitempty"`
	Config               *VPNConfig    `xml:"config,omitempty"`
}

// Opaque结构 - VPN服务器信息
type Opaque struct {
	IsFor         string   `xml:"is-for,attr"`    // "sg"
	TunnelGroup   string   `xml:"tunnel-group"`   // {{.Group}}
	GroupAlias    string   `xml:"group-alias"`    // {{.Group}}
	AggauthHandle int64    `xml:"aggauth-handle"` // 168179266
	ConfigHash    string   `xml:"config-hash"`    // 1595829378234
	AuthMethods   []string `xml:"auth-method"`    // multiple-cert, single-sign-on-v2
}

// 认证数据 - 核心交互结构
type Auth struct {
	ID      string `xml:"id,attr"`           // main|success|failure|otp-verification
	Title   string `xml:"title,omitempty"`   // 标题文本
	Message string `xml:"message,omitempty"` // 消息文本
	Banner  string `xml:"banner,omitempty"`  // 横幅信息
	Error   *Error `xml:"error,omitempty"`   // 错误信息
	Form    *Form  `xml:"form,omitempty"`    // 表单数据
}

func (auth *Auth) IsValid() bool { 
	return auth != nil
}

// 错误信息结构
type Error struct {
	ID     string `xml:"id,attr"`     // 错误代码
	Param1 string `xml:"param1,attr"` // 动态参数1
	Param2 string `xml:"param2,attr"` // 动态参数2
	Text   string `xml:",chardata"`   // 错误信息模板
}

// 表单结构
type Form struct {
	Method  string   `xml:"method,attr,omitempty"` // "post" - OTP中指定
	Action  string   `xml:"action,attr,omitempty"` // "/otp-verification" - OTP中指定
	Inputs  []Input  `xml:"input"`                 // 输入字段
	Selects []Select `xml:"select"`                // 选择字段
}

func (f *Form) IsValid() bool {
	return f != nil
}

// 输入字段
type Input struct {
	Type  string `xml:"type,attr"`  // text|password
	Name  string `xml:"name,attr"`  // username|password|secondary_password
	Label string `xml:"label,attr"` // 标签文本
}

// 选择字段
type Select struct {
	Name    string   `xml:"name,attr"`  // group_list
	Label   string   `xml:"label,attr"` // "GROUP:"
	Options []Option `xml:"option"`     // 选项列表
}

// 选项
type Option struct {
	Selected bool   `xml:"selected,attr,omitempty"` // 是否选中
	Value    string `xml:",chardata"`               // 选项值
}

// 能力集
type Capabilities struct {
	CryptoSupported []string `xml:"crypto-supported"` // ssl-dhe
}

// VPN配置数据
type VPNConfig struct {
	Client string `xml:"client,attr"` // "vpn"
	Type   string `xml:"type,attr"`   // "private"

	// VPN基础配置
	BaseConfig *VPNBaseConfig `xml:"vpn-base-config,omitempty"`

	// 客户端专用数据
	Opaque *OpaqueClient `xml:"opaque,omitempty"`

	// 配置文件清单
	ProfileManifest *VPNProfileManifest `xml:"vpn-profile-manifest,omitempty"`
}

type VPNBaseConfig struct {
	ServerCertHash string `xml:"server-cert-hash"` // {{.CertHash}}
}

type OpaqueClient struct {
	IsFor string `xml:"is-for,attr"` // "vpn-client"
}

type VPNProfileManifest struct {
	Profiles []VPNProfile `xml:"vpn"`
}

type VPNProfile struct {
	Rev   string        `xml:"rev,attr"` // "1.0"
	Files []ProfileFile `xml:"file"`
}

type ProfileFile struct {
	Type        string `xml:"type,attr"`         // "profile"
	ServiceType string `xml:"service-type,attr"` // "user"
	URI         string `xml:"uri"`               // "/profile_xxx.xml"
	Hash        Hash   `xml:"hash"`              // 哈希值
}

type Hash struct {
	Type  string `xml:"type,attr"` // "sha1"
	Value string `xml:",chardata"` // {{.ProfileHash}}
}
